/*
	@author Ivan Andonov
	@email ivan.andonov[at]gmail[dot]com

	@require library/jquery.js;
	
	@require sjs/Debug.js;
	@require sjs/Delegate.js;
	@require sjs/Events.js;
	@require sjs/MouseEvent.js;
	
	@minify yes;

*/

(function() {
	
	sjs.create('sjs.DraggableList', {
		
		// constructor
		initialize : function(listEl, url) {
			
			// PRIVATE VARS
			var list = jQuery(listEl);
			var listEl = listEl;
			var listName = listEl.id;
			
			var url = url;
			
			var sending = false;
			var enabled = true;
			vhistory = [];
			
			var dragIndex = null;
			var dropIndex = null;
			var tmpIndex = null;
			
			// PUBLIC VARS
			
			// PRIVATE METHODS
			function move(data, event) {
				//$log(this+'.move');
				event = window.event || event;
				event.data = data;
				if (this.timeout !== null) {
					clearTimeout(this.timeout);
				}
				var mEvent = new sjs.MouseEvent(event);
				var rows = this.getRows();
				var rowsCount = rows.length;
				var row = rows.eq(0);
				var rowsY = row.offset().top;
				var rowH = row.height();
				//var row = rows[0];
				//var rowsY = util.getElementY(row);
				//var rowH = util.getElementHeight(row);
				var index, y;
				for (var i = 0; i < rowsCount; i++) {
					y = rowsY+rowH*i;
					if (i === 0 && y > mEvent.y) {
						index = 0;
						break;
					} else if ((y < mEvent.y && y+rowH > mEvent.y) || i >= rowsCount-1) {
						index = i;
						break;
					}
				}
				if (index != this.tmpIndex) {
					//this.timeout = setTimeout($d(this, 'changePosition', this.tmpIndex, index), 10);
					$d(this, 'changePosition', this.tmpIndex, index)();
				}
			};
			
			// PUBLIC METHODS
			this.toString = function() {
				return sjs.DraggableList + '_' + this.listName;
			};
			
			this.drag = function(data, event) {
				//$log(this+'.drag');
				if (this.enabled) {
					event = window.event || event;
					event.data = data;
					this.dragIndex = 
					this.dropIndex = 
					this.tmpIndex = this.getHandlerIndex(event.data.handler);
					var row = this.getRow(this.tmpIndex);
					row.addClass(sjs.DraggableList.draggedClass);
					var handler = jQuery(event.data.handler);
					event.data.mousemove = $d(this, move, event.data);
					event.data.mouseup = $d(this, 'drop', event.data);
					event.data.selectstart = $d(this, function() { return false; }, event.data);
					this.mouseMoveId = sjs.Events.addEvent('document', 'onmousemove', $d(this, 'move', event.data));
					this.mouseUpId = sjs.Events.addEvent('document', 'onmouseup', $d(this, 'drop', event.data));
					document.onselectstart = function() {
						return false;
					}
				}
				return false;
			};
			
			this.drop = function(data, event) {
				//$log(this+'.drop');
				event = window.event || event;
				event.data = data;
				if (this.tmpIndex != this.dragIndex) {
					this.dropIndex = this.tmpIndex;
					this.update();
				}
				var row = this.getRow(this.dropIndex);
				row.removeClass(sjs.DraggableList.draggedClass);
				
				var handler = jQuery(event.data.handler);
				sjs.Events.removeEvent('document', 'onmousemove', this.mouseMoveId);
				sjs.Events.removeEvent('document', 'onmouseup', this.mouseUpId);
				document.onselectstart = null;
			};
			
		},
		
		// PUBLIC STATIC VARS
		listSelector : '.draggable_list',
		rowSelector : '.draggable',
		.handlerSelector : '.drag',
		draggedClass = 'dragged',
		url : 'admin/index/reorder',
		publicStaticVar : 'publicStaticVar',
		
		// PUBLIC STATIC METHODS
		publicStaticMethod : function() {
			return this.publicStaticVar+' '+privateStaticVar+' '+this;
		},
		
		init : function(list, listSelector) {
			//$log(this+'.init list='+list);
			if (list) {
				this.initList(null, list);
			} else {
				jQuery(listSelector || this.listSelector).each($d(this, 'initList'));
			}
		},
	
		initList : function(index, list, url) {
			if (list) {
				var listObj = new sjs.DraggableList(list, url);
			}
		}
		
	});
	
	// PRIVATE STATIC VARS
	var privateStaticVar = 'privateStaticVar';
	
	// PRIVATE STATIC METHODS
	function privateStaticMethod() {
		return privateStaticVar;
	}
	
})();

jQuery(document).ready(function() {
	sjs.DraggableList.init();
});